/*
 *  Copyright (C) 2010 Glauco
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.balisunrise.swing.builder;

import java.lang.reflect.Field;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTextField;
import org.balisunrise.annotation.FilterType;
import org.balisunrise.annotation.util.AnnotationsUtilitiesException;
import org.balisunrise.annotation.util.CriteriaUtilities;
import org.balisunrise.application.Application;
import org.balisunrise.application.BaliProperties;
import org.balisunrise.builder.BuilderException;
import org.balisunrise.common.FilterField;
import org.balisunrise.components.ComponentManager;
import org.balisunrise.swing.components.FieldLabel;
import org.balisunrise.swing.components.TextFieldInput;

/**
 *
 * @author Glauco
 */
public class FilterFieldBuilder 
        implements org.balisunrise.builder.FilterFieldBuilder{

    private static final String MESSAGE = "Erro ao construir uma FilterField.\n";

    public FilterField buildFilterField(Field field, String alias)
            throws BuilderException {

        if(field == null){
            throw new BuilderException(MESSAGE +
                    "field não pode ser nulo.");
        }

        if(alias == null){
            throw new BuilderException(MESSAGE +
                    "alias não pode ser nulo.");
        }

        try{
            return buildFilterField(CriteriaUtilities.create(field, alias));
        }catch(AnnotationsUtilitiesException auex){
            throw new BuilderException(MESSAGE +
                    auex.getMessage(), auex.getCause());
        }
    }

    public FilterField buildFilterField(CriteriaUtilities criteriaUtilities)
            throws BuilderException {

        if(criteriaUtilities == null){
            throw new BuilderException(MESSAGE +
                    "criteriaUtilities não pode ser nulo.");
        }

        switch(criteriaUtilities.type){
            case CriteriaUtilities.DEFINITION:
                return buildDefinition(criteriaUtilities);
            case CriteriaUtilities.EMBEDDED:
                return buildEmbedded(criteriaUtilities);
            case CriteriaUtilities.SELECTION:
                return buildSelection(criteriaUtilities);
        }

        throw new BuilderException(MESSAGE +
                    "Atributo TYPE do fieldUtilities invalido.");
    }

    private FilterField buildDefinition(CriteriaUtilities criteriaUtilities) {

        org.balisunrise.swing.transaction.FilterField ff =
                new org.balisunrise.swing.transaction.FilterField();

        // pega componentManager
        ComponentManager<?,JComponent> cm = Application.get()
                .getComponentManagers()
                .getComponentManager(criteriaUtilities.field.getType());

        // cria componentes
        //
        // label
        JLabel label = new JLabel(criteriaUtilities.label);
        String name = criteriaUtilities.field.getDeclaringClass().getName() +
                "_filterField_label_" + criteriaUtilities.field.getName() +
                "_" + criteriaUtilities.alias;
        label.setName(name);
        label.getAccessibleContext().setAccessibleName(name);
        label.setFocusable(false);
        // cria FieldLabel
        FieldLabel fieldLabel = new FieldLabel(label);
        fieldLabel.setOwner(ff);

        //
        // componente de filtro
        name = criteriaUtilities.field.getDeclaringClass().getName() +
                "_filterField_component_" + criteriaUtilities.field.getName() +
                "_" + criteriaUtilities.alias;
        JComponent component = cm.buildComponent(
                criteriaUtilities.properties);
        // cria FieldInput
        TextFieldInput textFieldInput = new TextFieldInput(
                    cm, (JTextField) component, true);
        textFieldInput.setOwner(ff);

        //
        // componentes between
        FieldLabel fieldLabelBetween = null;
        TextFieldInput textFieldInputBetween = null;
        if(criteriaUtilities.filterType == FilterType.BETWEEN){

            JLabel labelBetween = null;
            JComponent componentBetween = null;

            // label between
            name = criteriaUtilities.field.getDeclaringClass().getName() +
                    "_filterField_labelbetween_" +
                    criteriaUtilities.field.getName() +
                    "_" + criteriaUtilities.alias;
            labelBetween = new JLabel(
                    BaliProperties.getString(BaliProperties.messageTO));
            labelBetween.setName(name);
            labelBetween.getAccessibleContext().setAccessibleName(name);
            // cria FieldLabel
            fieldLabelBetween = new FieldLabel(labelBetween);
            fieldLabelBetween.setOwner(ff);

            // componente between
            name = criteriaUtilities.field.getDeclaringClass().getName() +
                "_filterField_componentBetween_" +
                criteriaUtilities.field.getName() +
                "_" + criteriaUtilities.alias;
            componentBetween = cm.buildComponent(
                criteriaUtilities.properties);
            // cria FieldInput
            textFieldInputBetween = new TextFieldInput(
                        cm, (JTextField) componentBetween, true);
            textFieldInputBetween.setOwner(ff);
        }

        // monta lista dos componentes
        ff.getFields().add(fieldLabel);
        ff.getFields().add(textFieldInput);
        if(criteriaUtilities.filterType == FilterType.BETWEEN){
            ff.getFields().add(fieldLabelBetween);
            ff.getFields().add(textFieldInputBetween);
        }

        // Cria FieldLayout
        ff.setJumpToNextRow(true);

        // atribui dados
        ff.setEmptyForAll(criteriaUtilities.emptyForAll);
        ff.setFieldClass(criteriaUtilities.field.getType());
        ff.setFieldName(criteriaUtilities.field.getName());
        ff.setFilterType(criteriaUtilities.filterType);
        
        return ff;
    }

    private FilterField buildEmbedded(CriteriaUtilities criteriaUtilities)
            throws BuilderException {

        throw new UnsupportedOperationException("Not implemented yet!");
    }

    private FilterField buildSelection(CriteriaUtilities criteriaUtilities) {
        
        throw new UnsupportedOperationException("Not implemented yet!");
    }

}
